package com.hsogoo.avatar;

import com.google.common.collect.Lists;
import com.hsogoo.avatar.enums.Protocol;
import com.hsogoo.avatar.exceptions.AvatarException;
import com.hsogoo.avatar.model.AvatarAddress;
import com.hsogoo.avatar.model.AvatarRequest;
import com.hsogoo.avatar.model.AvatarResponse;
import com.hsogoo.avatar.processor.DefaultAvatarProcessor;
import com.hsogoo.avatar.registry.AvatarRegistry;
import com.hsogoo.avatar.registry.RegisterMeta;
import com.hsogoo.avatar.registry.RegistryLoader;
import com.hsogoo.avatar.registry.ServiceMeta;
import com.hsogoo.avatar.registry.loadbanlance.LoadBalancer;
import com.hsogoo.avatar.registry.loadbanlance.RoundRobinLoadBalancer;
import com.hsogoo.avatar.transport.AvatarConnection;
import com.hsogoo.avatar.transport.AvatarConnector;
import com.hsogoo.avatar.transport.netty.AvatarNettyConnector;

import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;

/**
 * Created by za-huangsaigang on 2018/10/15.
 */
public class AvatarClient {

    private AvatarConnector connector;

    private AvatarRegistry registry;

    public AvatarClient withRegistry(AvatarRegistry registry){
        this.registry = registry;
        return this;
    }

    public AvatarConnector connector(){
        return connector;
    }

    public AvatarClient withConnector(AvatarConnector connector){
        this.connector = connector;
        return this;
    }

    public AvatarAddress lookup(ServiceMeta serviceMeta){
        List<AvatarAddress> providerList = Lists.newArrayList();
        Set<RegisterMeta> registerMetas = registry.lookup(serviceMeta);
        if (CollectionUtils.isEmpty(registerMetas)) {
            return null;
        }
        for(RegisterMeta registerMeta : registerMetas){
            providerList.add(registerMeta.getAddress());
        }
        LoadBalancer loadBalancer = new RoundRobinLoadBalancer(providerList);
        return loadBalancer.select();
    }

    public AvatarResponse sendRequest(AvatarAddress address, AvatarRequest request){
        if(connector == null){
            throw new AvatarException(String.format("connector must be not null"));
        }
        AvatarConnection connection = connector.connect(new AvatarAddress(address.getHost(), address.getPort()));
        return connection.channel().sendRequest(request);
    }

}
